-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(dogfood): add module #4
Conversation
The dogfooding module, as previously described, is used as the staking module for the Exocore chain. It allows operators and delegators to deposit and delegate their assets on a client chain for staking. The staked assets are then used to secure the Exocore chain. The parameters used by this module are the following: - EpochsUntilUnbonded, which represents the number of epochs after which an unbonding is effective. - EpochIdentifier, which is the identifier of the epoch duration. It should be valid according to the epoch keeper of `app.go`, and is thus constrained to the options week/day/hour. - MaxValidators, which is the maximum number of validators that will be forwarded to ABCI. - HistoricalEntries, which is the number of historical entries to persist in state. These are used by IBC.
The bootstrapping smart contract is responsible for accepting user deposits, operator registration, and delegations. These operations may flow freely until 24 hours (say) before the spawn time of Exocore, at which the contract will be locked. During this time, the genesis state of Exocore will be amended to record the initial deposits, delegations, operator registrations and public keys. The last of these will feed into the dogfooding module which will mark these operators as part of the initial validator set and allow block production. This PR includes the capability to load that state, and save the newly created operator information to disk. In addition, the staking hooks have been set up (partially) in this PR, which allow the SDK's slashing keeper to record validator signing rates for downtime slashing.
The operator module should restrict an operator from doing things that are logically not possible. For example, an operator that is already opted in should not be able to opt in again. Similarly, an operator who has opted out of a chain should not be able to replace the key for that chain without opting back in. Based on these assumptions, the comment maps out the list of possible operations that can happen within an epoch and is used to ensure that all of the cases result in the unbonding period being enforced accurately.
Whenever a delegation or undelegation event happens in the delegation module, the hooks are called. For both of these events, as long as the operator is not in the process of opting out from the chain, consensus key operations are queued to be applied at the end of the current epoch. For undelegation, specifically, the `recordKey` identifier of the undelegation is used to mark within the delegation module that the undelegation should be held until released at some point in the future (as opposed to releasing it after a fixed number of blocks, which is the default behaviour). This point in the future is calculated as the earlier of the unbonding period end, or the operator's opt out period end (if the operator is opting out).
The epochs hooks are used by the dogfood module to subscribe to the start and end times of epochs. After an epoch ends, the operations that are currently in the queue are upgraded to "pending", which are applied at the end of the block. The upgrades are also made to undelegation maturity, operator opt out, and operator key replacement data. Once the pending actions are applied, they are cleared from the queue. This branch is merged into dogfood-part5, which forms the basis of #121.
The validator set is not bound to change at each block. It can only change at the end of an epoch, or following a slashing event. Therefore, storing the historical information for each block is redundant. Instead, we create a validator set id corresponding to each validator set, and map each height to a validator set id. The mapping and the validator set id are pruned once the historical info for a height is not required. TODO: actually store the validator set against each id, within the `EndBlock` function at the end of the epoch.
The delegation module calls the records as undelegation records, and within itself stores the identifier for the record as the record key. The dogfood module should follow the same naming convention and call them undelegation record keys for clarity.
...and refactor getters / setters to `pending.go`.
* feat(dogfood): implement sdk staking interface The interface required by IBC was already implemented in `validators.go`. This PR takes that a step further and implements the interfaces required to use the dogfood module as a drop-in replacement for the SDK's staking module. The interfaces implemented are those expected by the slashing, evidence and `genutil` modules. An explanation has been provided above each function to explain why and where it is called, and if its implementation is really necessary. There are still some TODOs left in this PR that depend on the overall slashing / operator design. This branch is merged into dogfood-part6, which forms the basis of #122. * fix(dogfood): store val set id + val set at genesis, the val set id starts with 1. each time the validator set changes, the val set id of the current block is retrieved. for the next block, the val set is is stored as this id + 1. * fix(dogfood): increment val set id correctly in the case of genesis, we should not use height + 1 as the key in the mapping; rather, it should be height. in all other cases, the mapping key is height + 1. the value is the val set id in all cases.
feat(dogfood): implement epochs hooks + end block
feat(dogfood): implement delegation hooks
feat(dogfood): implement operator hooks
feat(dogfood): load genesis state for bootstrap
The `// #nosec G703` line needs to be placed above the multi-line statement that it is ignoring, not in the middle of the statement which contains the part to ignore.
* feat(dogfood): add asset_ids param * feat(dogfood): move to average pricing * fix(dogfood): relint, add epoch id for avg * chore(dogfood): golangci-lint * chore(dogfood): lint gosec again * fix(dogfood): use correct string for pubkey * fix(dogfood): ++ the undelegation hold count The line was accidentally deleted.
for key := range prev { | ||
bz := []byte(key) // undo string operation | ||
var keyObj tmprotocrypto.PublicKey | ||
k.cdc.MustUnmarshal(bz, &keyObj) // undo marshal operation | ||
res = append(res, abci.ValidatorUpdate{ | ||
PubKey: keyObj, | ||
Power: 0, | ||
}) | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
for k := range m.List { | ||
v := m.List[k] | ||
baseI := i | ||
i = encodeVarintDogfood(dAtA, i, uint64(v)) | ||
i-- | ||
dAtA[i] = 0x10 | ||
i -= len(k) | ||
copy(dAtA[i:], k) | ||
i = encodeVarintDogfood(dAtA, i, uint64(len(k))) | ||
i-- | ||
dAtA[i] = 0xa | ||
i = encodeVarintDogfood(dAtA, i, uint64(baseI-i)) | ||
i-- | ||
dAtA[i] = 0xa | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
for k, v := range m.List { | ||
_ = k | ||
_ = v | ||
mapEntrySize := 1 + len(k) + sovDogfood(uint64(len(k))) + 1 + sovDogfood(uint64(v)) | ||
n += mapEntrySize + 1 + sovDogfood(uint64(mapEntrySize)) | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. It looks like the PR has already been reviewed in the old repo.
Dogfooding is the practice of using one's own products or services. The module allows assets deposited on a client chain to be used to secure the Exocore chain.
genesis.json
file using a trust-minimized (verifiable) approach which is done via the bootstrapping contract.impl_sdk.go
.Note that this module is not responsible for distributing rewards to the operators and delegators; it will have to be created separately.
Supersedes ExocoreNetwork/exocore-private#114 from the older repo.